package com.ruleengine.worker.runner.rule.compute;

import static com.ruleengine.worker.runner.rule.RuleArgsField.COMPUTE_RULE_MAP_KEY;

import java.nio.charset.StandardCharsets;

import com.api.jsonata4java.expressions.Expressions;
import com.fasterxml.jackson.databind.JsonNode;
import com.ruleengine.util.JsonUtil;
import com.ruleengine.util.exception.JsonException;
import com.ruleengine.util.model.Message;
import com.ruleengine.worker.model.Rule;
import com.ruleengine.worker.runner.rule.PubSubRuleRunner;

import io.vertx.core.Vertx;
import lombok.extern.slf4j.Slf4j;

/**
 * @author lianghanwei on 2024/3/20
 */
@Slf4j
public class JsonMapRuleRunner extends PubSubRuleRunner<Message, Message> {

    private final String mapExpression;

    public JsonMapRuleRunner(Vertx vertx, String name, Rule rule) {
        super(vertx, name, rule);
        this.mapExpression = rule.getSpec().getArgs().get(COMPUTE_RULE_MAP_KEY);
    }

    @Override
    public Message process(Message item) {
        // TODO-lhw-2024/03/20: Valid json
        String jsonMsg = new String(item.getMessage());
        JsonNode jsonNode = JsonUtil.parseJsonNode(jsonMsg);

        try {
            Expressions expr = Expressions.parse(mapExpression);
            JsonNode result = expr.evaluate(jsonNode);
            if (result == null) {
                log.info("Map expression={}, map result of this json is null", mapExpression);
                return null;
            } else {
                Message mapItem = item.toBuilder()
                    .message(JsonUtil.toPrettyJson(result).getBytes(StandardCharsets.UTF_8))
                    .build();

                log.info("Map expression={}, map result of this json={}", mapExpression, new String(mapItem.getMessage()));
                return mapItem;
            }
        } catch (Exception e) {
            log.error("Process mapExpression failed", e);
            throw new JsonException("Process mapExpression failed", e);
        }
    }
}
